package com.mazaiting.socket.server.work;

import com.mazaiting.socket.server.entity.NioRequest;
import com.mazaiting.socket.server.entity.ServerConfig;
import com.mazaiting.socket.server.handler.IChannelHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * 工作线程
 */
public class NioWorker implements Runnable {
    /**
     * 日志工具
     */
    private final Logger logger = LoggerFactory.getLogger(getClass());
    /**
     * 选择键
     */
    private final SelectionKey key;

    /**
     * 通道
     */
    private final SocketChannel channel;

    /**
     * 服务器配置
     */
    private final ServerConfig serverConfig;
    /**
     * 请求内容
     */
    private final String requestStr;
    /**
     * 通道处理器
     */
    private final IChannelHandler channelHandler;

    public NioWorker(SelectionKey key, ServerConfig serverConfig, String requestStr, IChannelHandler channelHandler) {
        this.key = key;
        this.channel = (SocketChannel) key.channel();
        this.serverConfig = serverConfig;
        this.requestStr = requestStr;
        this.channelHandler = channelHandler;
    }

    @Override
    public void run() {
        // 远程地址
        SocketAddress remoteAddress = null;
        String response = "";
        try {
            remoteAddress = channel.getRemoteAddress();
            logger.debug("接收到" + remoteAddress + "的内容: " + requestStr);
            // 如果配置了 channel 则使用 handler 处理
            if (Objects.nonNull(channelHandler)) {
                NioRequest nioRequest = new NioRequest(serverConfig, channel, requestStr);
                // 处理具体逻辑
                response = channelHandler.handle(nioRequest);
            }
        } catch (Exception e) {
            logger.error(remoteAddress + "响应异常: " + e.getMessage());
            response = e.getMessage();
        }
        logger.debug("响应给" + remoteAddress + "的内容: " + response);
        // 设置输出内容
        byte[] bytes = response.getBytes(StandardCharsets.UTF_8);
        ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
        byteBuffer.put(response.getBytes(StandardCharsets.UTF_8));
        byteBuffer.flip();
        // 将输出流绑定至附件
        key.attach(byteBuffer);
        // 注册写事件
        key.interestOps(SelectionKey.OP_WRITE);
        // 唤醒
        key.selector().wakeup();
    }
}